package cn.harry.cabinet.view

import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import cn.harry.cabinet.R
import cn.harry.cabinet.hardware.HardwareDeviceManager
import cn.harry.cabinet.hardware.device.CardReaderDevice
import cn.harry.cabinet.model.entity.UsageRecord
import cn.harry.cabinet.model.entity.User
import cn.harry.cabinet.model.enums.DeviceType
import cn.harry.cabinet.model.enums.OperationType
import cn.harry.cabinet.model.ui.HardwareDeviceUI
import cn.harry.cabinet.repository.CardRepository
import cn.harry.cabinet.repository.HardwareDeviceRepository
import cn.harry.cabinet.repository.UsageRecordRepository
import cn.harry.cabinet.utils.VoiceHelper
import cn.harry.cabinet.utils.logCardOperation
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Date

/**
 * 刷卡验证页面
 */
class CardScanActivity : BaseAuthActivity() {

    companion object {
        private const val TAG = "CardScanActivity"
    }

    private lateinit var statusText: TextView
    private lateinit var hardwareDeviceRepository: HardwareDeviceRepository
    private lateinit var cardRepository: CardRepository
    private lateinit var usageRecordRepository: UsageRecordRepository
    private var cardReaderDevice: CardReaderDevice? = null
    private var cardReaderListenerJob: Job? = null
    private var isProcessing = false
    private var isInitialized = false  // 标记是否已完成初始化
    
    // 用户信息（仅在取操作时有值，从人脸识别页面传递过来）
    private var currentUser: User? = null
    
    // 加载点动画
    private var loadingDotsJob: Job? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_card_scan)

        // 初始化Repository
        hardwareDeviceRepository = HardwareDeviceRepository(application)
        cardRepository = CardRepository(application)
        usageRecordRepository = UsageRecordRepository(application)
        
        // 获取用户信息（仅在取操作时有值）
        val userId = intent.getLongExtra("user_id", 0L)
        val userName = intent.getStringExtra("user_name") ?: ""
        val employeeId = intent.getStringExtra("employee_id") ?: ""
        
        if (userId > 0 && userName.isNotEmpty()) {
            // 从Intent获取用户信息（取操作）
            currentUser = User(
                id = userId,
                name = userName,
                employeeId = employeeId,
                phoneNumber = "",
                position = "",
                gender = cn.harry.cabinet.model.enums.Gender.MALE,
                status = cn.harry.cabinet.model.enums.UserStatus.ENABLED,
                featureCode = "",
                password = ""
            )
            android.util.Log.i(TAG, "取操作模式 - 用户: ${currentUser?.name}")
        } else {
            android.util.Log.i(TAG, "还操作模式 - 无用户信息")
        }

        // 初始化视图
        initViews()

        // 应用主题
        applyTheme()

        // 设置点击事件
        setupClickListeners()

        // 初始化并连接读卡器
        initAndConnectCardReader()
    }

    private fun initViews() {
        statusText = findViewById(R.id.tv_status)

        // 更新标题
        val titleText = findViewById<TextView>(R.id.tv_title)
        titleText.text = getPageTitle("刷卡验证")
        
        // 启动加载点动画
        startLoadingDotsAnimation()
        
        // 语音播报提示
        VoiceHelper.speak("请将仪器靠近读卡区域")
    }
    
    /**
     * 启动加载点动画
     */
    private fun startLoadingDotsAnimation() {
        val dot1 = findViewById<android.view.View>(R.id.dot1)
        val dot2 = findViewById<android.view.View>(R.id.dot2)
        val dot3 = findViewById<android.view.View>(R.id.dot3)
        
        loadingDotsJob = lifecycleScope.launch {
            var step = 0
            while (true) {
                when (step % 3) {
                    0 -> {
                        dot1.alpha = 1f
                        dot2.alpha = 0.4f
                        dot3.alpha = 0.2f
                    }
                    1 -> {
                        dot1.alpha = 0.2f
                        dot2.alpha = 1f
                        dot3.alpha = 0.4f
                    }
                    2 -> {
                        dot1.alpha = 0.4f
                        dot2.alpha = 0.2f
                        dot3.alpha = 1f
                    }
                }
                step++
                delay(500)
            }
        }
    }

    private fun setupClickListeners() {
        findViewById<ImageView>(R.id.btn_back)?.setOnClickListener {
            finish()
        }
    }

    /**
     * 初始化并连接读卡器
     */
    private fun initAndConnectCardReader() {
        statusText.text = "正在初始化读卡器..."

        lifecycleScope.launch {
            try {
                // 从数据库获取刷卡器配置
                val cardReaderDevice = withContext(Dispatchers.IO) {
                    hardwareDeviceRepository.getDeviceByType(DeviceType.CARD_READER)
                }

                if (cardReaderDevice == null) {
                    statusText.text = "读卡器配置不存在，请先配置硬件设备"
                    Toast.makeText(this@CardScanActivity, "读卡器配置不存在", Toast.LENGTH_SHORT).show()
                    android.util.Log.e(TAG, "读卡器配置不存在")
                    return@launch
                }

                // 使用数据库配置
                val config = HardwareDeviceUI.fromEntity(cardReaderDevice)
                android.util.Log.i(TAG, "使用数据库刷卡器配置")

                // 连接读卡器
                connectCardReader(config)

            } catch (e: Exception) {
                statusText.text = "初始化失败: ${e.message}"
                Toast.makeText(this@CardScanActivity, "初始化失败", Toast.LENGTH_SHORT).show()
                android.util.Log.e(TAG, "初始化读卡器失败", e)
            }
        }
    }

    /**
     * 连接读卡器
     */
    private suspend fun connectCardReader(config: HardwareDeviceUI) {
        try {
            val hardwareManager = HardwareDeviceManager.getInstance(this@CardScanActivity)

            android.util.Log.i(
                TAG,
                "准备连接刷卡器 - 串口: ${config.serialPort}, 波特率: ${config.baudRate}"
            )

            // 检查是否已经连接
            if (!hardwareManager.isConnected.value) {
                android.util.Log.i(TAG, "开始连接串口...")
                statusText.text = "正在连接读卡器..."

                val success = hardwareManager.connectAndInitialize()

                if (!success) {
                    statusText.text = "串口连接失败"
                    Toast.makeText(this, "串口连接失败", Toast.LENGTH_SHORT).show()
                    VoiceHelper.speak("读卡器连接失败")
                    android.util.Log.e(TAG, "串口连接失败 - 路径: ${config.serialPort}")
                    return
                }

                android.util.Log.i(TAG, "串口连接成功，等待稳定...")
                delay(500)
            } else {
                android.util.Log.i(TAG, "串口已连接，直接使用现有连接")
            }
            
            // 获取刷卡器设备实例（无论新连接还是复用连接都需要获取）
            cardReaderDevice = hardwareManager.getCardReaderDevice()
            android.util.Log.i(
                TAG,
                "刷卡器设备实例: ${if (cardReaderDevice != null) "已获取" else "null"}"
            )
            
            // 检查设备实例是否获取成功
            if (cardReaderDevice == null) {
                statusText.text = "读卡器设备获取失败"
                Toast.makeText(this, "读卡器设备获取失败", Toast.LENGTH_SHORT).show()
                VoiceHelper.speak("读卡器设备获取失败")
                android.util.Log.e(TAG, "读卡器设备实例为null")
                return
            }

            // 清除之前的刷卡事件缓存，避免处理旧记录
            android.util.Log.i(TAG, "清除刷卡事件缓存...")
            cardReaderDevice?.clearCardReadEvent()
            
            // 启动刷卡器自动监听
            android.util.Log.i(TAG, "准备启动刷卡器自动监听...")
            cardReaderDevice?.startAutoListening()

            // 设置刷卡事件监听
            setupCardReaderListener()

            statusText.text = "请刷卡..."
            Toast.makeText(this, "刷卡器已就绪", Toast.LENGTH_SHORT).show()
            android.util.Log.i(TAG, "✅ 刷卡器连接成功，监听已启动")
            
            // 延迟标记初始化完成，避免启动时的误触发
            lifecycleScope.launch {
                delay(500)  // 延迟500ms
                isInitialized = true
                android.util.Log.i(TAG, "刷卡器初始化完成，开始接受刷卡事件")
            }

        } catch (e: Exception) {
            statusText.text = "连接失败: ${e.message}"
            Toast.makeText(this, "连接失败", Toast.LENGTH_SHORT).show()
            android.util.Log.e(TAG, "刷卡器连接失败", e)
        }
    }

    /**
     * 设置刷卡器监听
     */
    private fun setupCardReaderListener() {
        android.util.Log.i(TAG, "开始设置刷卡器监听...")
        cardReaderListenerJob = lifecycleScope.launch {
            android.util.Log.i(TAG, "刷卡器监听协程已启动")
            cardReaderDevice?.cardReadEvent
                ?.filterNotNull()  // 过滤掉null值，只处理真实的刷卡事件
                ?.collect { cardInfo ->
                    android.util.Log.i(TAG, "收到刷卡事件 - 卡号: ${cardInfo.cardId}")
                    handleCardReadEvent(cardInfo)
                }
        }
        android.util.Log.i(TAG, "刷卡器监听设置完成")
    }

    /**
     * 处理刷卡事件
     * 两层逻辑：
     * 1. 取：先人脸识别认证，认证成功后进入刷卡页面（携带用户信息），刷卡验证卡号是否存在，存在则绑定并记录
     * 2. 还：刷卡验证卡号是否存在，存在则查询未归还记录并更新
     */
    private fun handleCardReadEvent(cardInfo: CardReaderDevice.CardInfo) {
        android.util.Log.i(TAG, "进入handleCardReadEvent - isInitialized: $isInitialized, isProcessing: $isProcessing")
        
        // 检查是否已完成初始化
        if (!isInitialized) {
            android.util.Log.w(TAG, "刷卡器尚未完成初始化，忽略此次刷卡事件")
            return
        }
        
        if (isProcessing) {
            android.util.Log.w(TAG, "正在处理中，忽略此次刷卡事件")
            return
        }

        isProcessing = true
        val cardNumber = cardInfo.cardId  // 使用原始卡号

        android.util.Log.i(TAG, "✅ 开始处理刷卡 - 卡号: $cardNumber")
        statusText.text = "正在验证卡号: $cardNumber"

        lifecycleScope.launch {
            try {
                // 验证卡号是否存在于Card表中
                val card = withContext(Dispatchers.IO) {
                    cardRepository.getByCardNumber(cardNumber)
                }

                if (card == null) {
                    // 卡号不存在
                    withContext(Dispatchers.Main) {
                        statusText.text = "卡号不存在，请重新刷卡"
                        Toast.makeText(
                            this@CardScanActivity,
                            "卡号 $cardNumber 不存在",
                            Toast.LENGTH_SHORT
                        ).show()

                        // 语音播报提示
                        VoiceHelper.speak("该卡号不存在")
                        isProcessing = false
                        cardReaderDevice?.clearCardReadEvent()
                    }
                    return@launch
                }

                // 检查卡片状态
                if (card.status != cn.harry.cabinet.model.entity.Card.STATUS_ENABLED) {
                    withContext(Dispatchers.Main) {
                        statusText.text = "卡片已禁用"
                        Toast.makeText(
                            this@CardScanActivity,
                            "卡片 $cardNumber 已禁用",
                            Toast.LENGTH_SHORT
                        ).show()
                        isProcessing = false
                        cardReaderDevice?.clearCardReadEvent()
                    }
                    return@launch
                }

                // 根据操作类型判断是取操作还是还操作
                when (actionType) {
                    ACTION_TAKE -> {
                        // 取操作：需要用户信息，创建新的使用记录
                        if (currentUser != null) {
                            handleTakeOperation(cardNumber, currentUser!!)
                        } else {
                            withContext(Dispatchers.Main) {
                                statusText.text = "取操作需要先进行人脸识别"
                                Toast.makeText(
                                    this@CardScanActivity,
                                    "请先完成人脸识别",
                                    Toast.LENGTH_SHORT
                                ).show()
                                isProcessing = false
                                cardReaderDevice?.clearCardReadEvent()
                            }
                        }
                    }
                    ACTION_RETURN -> {
                        // 还操作：查询并更新未归还记录
                        handleReturnOperation(cardNumber)
                    }
                    else -> {
                        withContext(Dispatchers.Main) {
                            statusText.text = "未知操作类型"
                            Toast.makeText(
                                this@CardScanActivity,
                                "操作类型错误",
                                Toast.LENGTH_SHORT
                            ).show()
                            isProcessing = false
                            cardReaderDevice?.clearCardReadEvent()
                        }
                    }
                }

            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    statusText.text = "操作失败: ${e.message}"
                    Toast.makeText(this@CardScanActivity, "操作失败: ${e.message}", Toast.LENGTH_SHORT).show()
                    android.util.Log.e(TAG, "处理刷卡事件失败", e)
                    isProcessing = false
                    cardReaderDevice?.clearCardReadEvent()
                }
            }
        }
    }
    
    /**
     * 处理取操作
     * 创建新的使用记录，绑定用户和卡号
     */
    private suspend fun handleTakeOperation(cardNumber: String, user: User) {
        try {
            // 创建使用记录
            val usageRecord = UsageRecord(
                employeeId = user.employeeId,
                name = user.name,
                cardNumber = cardNumber,
                status = OperationType.RETRIEVE,
                takeTime = Date(),
                returnTime = null
            )
            
            val recordId = withContext(Dispatchers.IO) {
                usageRecordRepository.insert(usageRecord)
            }
            
            withContext(Dispatchers.Main) {
                statusText.text = "取出成功！"
                Toast.makeText(
                    this@CardScanActivity,
                    "取出成功！\n用户: ${user.name}\n卡号: $cardNumber",
                    Toast.LENGTH_SHORT
                ).show()
                
                android.util.Log.i(TAG, "取操作成功 - 用户: ${user.name}, 卡号: $cardNumber, 记录ID: $recordId")
                
                // 记录操作日志
                logCardOperation(
                    scope = lifecycleScope,
                    operationType = cn.harry.cabinet.constants.OperationLogConstants.OperationType.INSTRUMENT_TAKE,
                    result = cn.harry.cabinet.constants.OperationLogConstants.Result.SUCCESS,
                    description = "取出成功 - 用户: ${user.name}",
                    cardNumber = cardNumber,
                    userId = user.id,
                    employeeId = user.employeeId,
                    userName = user.name,
                    detailData = "记录ID: $recordId"
                )

                // 语音播报提示
                VoiceHelper.speak("取出成功")
                // 延迟后返回首页
                delay(1500)
                finish()
            }
            
        } catch (e: Exception) {
            withContext(Dispatchers.Main) {
                statusText.text = "记录失败: ${e.message}"
                Toast.makeText(
                    this@CardScanActivity,
                    "记录失败: ${e.message}",
                    Toast.LENGTH_SHORT
                ).show()
                android.util.Log.e(TAG, "取操作失败", e)
                
                // 记录失败日志
                logCardOperation(
                    scope = lifecycleScope,
                    operationType = cn.harry.cabinet.constants.OperationLogConstants.OperationType.INSTRUMENT_TAKE,
                    result = cn.harry.cabinet.constants.OperationLogConstants.Result.FAILED,
                    description = "取出失败 - 用户: ${user.name}",
                    cardNumber = cardNumber,
                    userId = user.id,
                    employeeId = user.employeeId,
                    userName = user.name,
                    errorMessage = e.message
                )
                
                isProcessing = false
                cardReaderDevice?.clearCardReadEvent()
            }
        }
    }
    
    /**
     * 处理还操作
     * 查询未归还的记录并更新归还时间
     */
    private suspend fun handleReturnOperation(cardNumber: String) {
        try {
            // 查询未归还的记录
            val unreturnedRecord = withContext(Dispatchers.IO) {
                usageRecordRepository.getUnreturnedRecordByCardNumber(cardNumber)
            }
            
            if (unreturnedRecord == null) {
                withContext(Dispatchers.Main) {

                    VoiceHelper.speak("未找到取出记录")

                    statusText.text = "未找到取出记录"
                    Toast.makeText(
                        this@CardScanActivity,
                        "卡号 $cardNumber 没有未归还的记录",
                        Toast.LENGTH_SHORT
                    ).show()
                    
                    // 记录失败日志
                    logCardOperation(
                        scope = lifecycleScope,
                        operationType = cn.harry.cabinet.constants.OperationLogConstants.OperationType.INSTRUMENT_RETURN,
                        result = cn.harry.cabinet.constants.OperationLogConstants.Result.FAILED,
                        description = "归还失败 - 未找到取出记录",
                        cardNumber = cardNumber,
                        errorMessage = "卡号 $cardNumber 没有未归还的记录"
                    )
                    
                    isProcessing = false
                    cardReaderDevice?.clearCardReadEvent()
                }
                return
            }
            
            // 更新归还时间
            val updatedRecord = unreturnedRecord.copy(
                returnTime = Date(),
                status = OperationType.STORE
            )
            
            withContext(Dispatchers.IO) {
                usageRecordRepository.update(updatedRecord)
            }
            
            withContext(Dispatchers.Main) {
                statusText.text = "归还成功！"
                Toast.makeText(
                    this@CardScanActivity,
                    "归还成功！\n用户: ${unreturnedRecord.name}\n卡号: $cardNumber",
                    Toast.LENGTH_LONG
                ).show()
                
                android.util.Log.i(TAG, "还操作成功 - 用户: ${unreturnedRecord.name}, 卡号: $cardNumber")
                
                // 记录操作日志
                logCardOperation(
                    scope = lifecycleScope,
                    operationType = cn.harry.cabinet.constants.OperationLogConstants.OperationType.INSTRUMENT_RETURN,
                    result = cn.harry.cabinet.constants.OperationLogConstants.Result.SUCCESS,
                    description = "归还成功 - 用户: ${unreturnedRecord.name}",
                    cardNumber = cardNumber,
                    userId = unreturnedRecord.id,
                    employeeId = unreturnedRecord.employeeId,
                    userName = unreturnedRecord.name
                )

                // 语音播报提示
                VoiceHelper.speak("归还成功")
                // 延迟后返回主页
                delay(2000)
                finish()
            }
            
        } catch (e: Exception) {
            withContext(Dispatchers.Main) {
                statusText.text = "归还失败: ${e.message}"
                Toast.makeText(
                    this@CardScanActivity,
                    "归还失败: ${e.message}",
                    Toast.LENGTH_SHORT
                ).show()
                android.util.Log.e(TAG, "还操作失败", e)
                
                // 记录失败日志
                logCardOperation(
                    scope = lifecycleScope,
                    operationType = cn.harry.cabinet.constants.OperationLogConstants.OperationType.INSTRUMENT_RETURN,
                    result = cn.harry.cabinet.constants.OperationLogConstants.Result.FAILED,
                    description = "归还失败",
                    cardNumber = cardNumber,
                    errorMessage = e.message
                )
                
                isProcessing = false
                cardReaderDevice?.clearCardReadEvent()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        try {
            // 重置初始化标志
            isInitialized = false
            
            // 取消监听任务
            cardReaderListenerJob?.cancel()
            
            // 停止加载点动画
            loadingDotsJob?.cancel()

            // 停止刷卡器监听
            cardReaderDevice?.stopAutoListening()

            android.util.Log.i(TAG, "刷卡器监听已停止")
        } catch (e: Exception) {
            android.util.Log.e(TAG, "停止刷卡器失败", e)
        }
    }
}
